package com.css.devops.service.jenkins;

import java.io.IOException;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.css.devops.component.JenkinsBasicComponent;
import com.css.devops.constants.DevopsConstants;
import com.css.devops.domain.DevopsComputer;
import com.css.devops.domain.DevopsPlugin;
import com.css.devops.service.DevopsApi;
import com.css.devops.utils.JsonMapperUtils;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.offbytwo.jenkins.JenkinsServer;
import com.offbytwo.jenkins.model.Computer;
import com.offbytwo.jenkins.model.LabelWithDetails;
import com.offbytwo.jenkins.model.Plugin;
import com.offbytwo.jenkins.model.PluginManager;

import cn.hutool.http.HttpException;
import cn.hutool.http.HttpResponse;
import lombok.extern.slf4j.Slf4j;

/**
 * 获取 Jenkins 相关信息
 *
 * 例如获取插件信息、获取Label信息、关闭Jenkins等
 */
@Slf4j
@Service("jenkinsApiService")
public class JenkinsApiService implements DevopsApi {

    /**
     * Jenkins 对象
     */
	@Autowired
    private JenkinsServer jenkinsServer;

	@Autowired
	private JenkinsBasicComponent jenkinsBasicComponent;

	/**
	 * 初始化
	 */
	@Override
	public void init() {
		try {
			String jenkinsLogin = String.format(DevopsConstants.JENKINS_CRUMB, StringUtils.EMPTY);
			HttpResponse response = jenkinsBasicComponent.getRequest(jenkinsLogin);
			
			String result = response.body();
			if(JsonMapperUtils.getInstance().isValidJson(result)) {
				JsonNode rootNode = JsonMapperUtils.getInstance().readTree(result);
				
				String crumb = rootNode.path("crumb").asText();
		        String crumbRequestField = rootNode.path("crumbRequestField").asText();
		        
		        Map<String,String> headers = Maps.newConcurrentMap();
		        headers.put(crumbRequestField, crumb);
		        
		        Map<String,String> formMap = Maps.newConcurrentMap();
		        String script = "hudson.security.csrf.GlobalCrumbIssuerConfiguration.DISABLE_CSRF_PROTECTION=true";
		        formMap.put("script", script);
		        formMap.put(crumbRequestField, crumb);
		        
		        response = jenkinsBasicComponent.postRequest(DevopsConstants.JENKINS_SCRIPT, headers, formMap);
		        log.info("Jenkins 设置CSRF成功，返回值:{}",response.getStatus());
			}else {
				log.info("无需设置Jenkins的CSRF");
			}
		} catch (JsonProcessingException | HttpException e) {
			log.error(e.getMessage(), e);
			log.warn("无需关注该错误!");
		}
	}
    /**
     * 获取主机信息
     */
    @Override
	@SuppressWarnings("rawtypes")
	public List<DevopsComputer> getComputerInfo() {
    	List<DevopsComputer> devopsComputers = Lists.newArrayList();
        try {
            Map<String, Computer> map = jenkinsServer.getComputers();
            for (Computer computer : map.values()) {
            	DevopsComputer devopsComputer = new DevopsComputer();
                Map<String, Map> monitorData = computer.details().getMonitorData();
                devopsComputer.setDisplayName(computer.details().getDisplayName());
                devopsComputer.setNumExecutors(computer.details().getNumExecutors());
                devopsComputer.setOffline(computer.details().getOffline());
                devopsComputer.setMonitorData(monitorData);
                
                devopsComputers.add(devopsComputer);
            }
        } catch (IOException e) {
        	log.error(e.getMessage(), e);
        }
        return devopsComputers;
    }

    /**
     * 重启 Jenkins
     */
    @Override
	public void restart() {
        try {
            jenkinsServer.restart(true);
        } catch (IOException e) {
        	log.error(e.getMessage(), e);
        }
    }

    /**
     * 安全重启 Jenkins
     */
    @Override
	public void safeRestart() {
        try {
            jenkinsServer.safeRestart(true);
        } catch (IOException e) {
        	log.error(e.getMessage(), e);
        }
    }

    /**
     * 安全结束 Jenkins
     */
    @Override
	public void safeExit() {
        try {
            jenkinsServer.safeExit(true);
        } catch (IOException e) {
        	log.error(e.getMessage(), e);
        }
    }

    /**
     * 关闭 Jenkins 连接
     */
    @Override
	public void close() {
        jenkinsServer.close();
    }

    /**
     * 根据 Label 查找代理节点信息
     */
    @Override
	public void getLabelNodeInfo() {
        try {
            LabelWithDetails labelWithDetails = jenkinsServer.getLabel("jnlp-agent");
            // 获取标签名称
            System.out.println(labelWithDetails.getName());
            // 获取 Cloud 信息
            System.out.println(labelWithDetails.getClouds());
            // 获取节点信息
            System.out.println(labelWithDetails.getNodeName());
            // 获取关联的 Job
            System.out.println(labelWithDetails.getTiedJobs());
            // 获取参数列表
            System.out.println(labelWithDetails.getPropertiesList());
            // 是否脱机
            System.out.println(labelWithDetails.getOffline());
            // 获取描述信息
            System.out.println(labelWithDetails.getDescription());
        } catch (IOException e) {
        	log.error(e.getMessage(), e);
        }
    }

    /**
     * 判断 Jenkins 是否运行
     */
    @Override
	public boolean isRunning() {
        boolean isRunning = jenkinsServer.isRunning();
        return isRunning;
    }

    /**
     * 获取 Jenkins 插件信息
     */
    @Override
	public List<DevopsPlugin> getPluginInfo(){
    	List<DevopsPlugin> devopsPlugins = Lists.newArrayList();
        try {
        	DevopsPlugin devopsPlugin = null;
            PluginManager pluginManager =jenkinsServer.getPluginManager();
            // 获取插件列表
            List<Plugin> plugins = pluginManager.getPlugins();
            for (Plugin plugin:plugins){
                devopsPlugin = new DevopsPlugin();
                devopsPlugin.setLongName(plugin.getLongName());
                devopsPlugin.setUrl(plugin.getUrl());
                devopsPlugin.setVersion(plugin.getVersion());
                devopsPlugin.setShortName(plugin.getShortName());
                devopsPlugin.setActive(plugin.isActive());
                devopsPlugin.setSupportsDynamicLoad(plugin.getSupportsDynamicLoad());
                devopsPlugins.add(devopsPlugin);
            }
        } catch (IOException e) {
        	log.error(e.getMessage(), e);
        }
        return devopsPlugins;
    }

}
